package com.lmx.local.business;

import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.PropertiesFileUtil;
import com.lmx.local.SocketClient;
import com.lmx.persistence.service.local.LocalCameraService;
import com.lmx.repoDomain.tmodel.LsMessage;

import net.bramp.ffmpeg.FFprobe;
import net.bramp.ffmpeg.probe.FFmpegFormat;
import net.bramp.ffmpeg.probe.FFmpegProbeResult;
import net.bramp.ffmpeg.probe.FFmpegStream;
/**
 * 直播流监听以及处理
 * 
 * @author 梁慕学
 * @version 1.00
 */
public class LiveStreamListener {
    private Log logger = LogFactory.getLog(this.getClass());
    
    private Properties properties = PropertiesFileUtil.getApplicationProperties();
    
    @Autowired
    protected LocalCameraService cameraService;
    
    @Autowired
    protected SocketClient client;
   
    private final ExecutorService pool = Executors.newFixedThreadPool(10);

    public static final ProcessListener DEFAULT_PROCESS_LISTENER = new ProcessListener(StringUtils.EMPTY);

    private String ip;//推流ip
    private Process process;//运行视频推流的进程对象
    private String businessId;//此次拉流请求的业务序号
    private String deviceCode;//拉流请求对应的摄像头序列号
    
    public LiveStreamListener(){
        
    }
    
    public LiveStreamListener(String ip){
        this.ip = ip;
        //通过ip找出对应的序列号
//        Camera c = cameraService.findByIp(ip);
//        if(c!=null){
//            this.deviceCode = c.getCode();  
//        }
    }
 
    public LiveStreamListener(String ip,String deviceCode){
        this.ip = ip;
        this.deviceCode = deviceCode;
    }
    
    public void startRemoteLiveCheck(){
        pool.submit(() -> {
            //接收到推流成功后，进行云端拉流尝试，拉流成功后再通知云端业务服务器
            while(true){
                String url = "rtmp://47.104.2.109:1935/hls/100384215";
                boolean flag = isStreamInLive(url);
                if(flag){
                   //发送拉流ready的通知
                   this.sendPrgressInfo(2);
                   break; 
                }
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    logger.warn("sleep err",e);
                }
            }
        });       

    }

    /*
     * 检查云端流是否ready
     * @param String url 云端流地址
     */
    public boolean isStreamInLive(String url){
        String ffprobeCommandPath = properties.getProperty("local.camera.ffprobeCommandPath");
        FFprobe ffprobe;
        try {
            ffprobe = new FFprobe(ffprobeCommandPath);
        } catch (IOException e) {
            logger.error("ffprobeCommandPath fail",e);
            return false;
        }
        FFmpegProbeResult probeResult;
        try {
            probeResult = ffprobe.probe(url);
            FFmpegFormat format = probeResult.getFormat();
            FFmpegStream stream = probeResult.getStreams().get(0);
            logger.debug("stream.codec_long_name:" + stream.codec_long_name);
            return true;
        } catch (IOException e) {
            logger.info("probeResult fail",e);
            return false;
        }
    
    }
    
    /*
     * 发送拉流状态信息
     * @param Integer liveStatus
     */
    public void sendPrgressInfo(Integer liveStatus){
        LsMessage msg = new LsMessage();
        msg.setCode("1001");
        msg.setBusinessId(businessId);
        msg.setSuccess(1);
        msg.setDeviceCode(deviceCode);
        msg.setCreateTime(CommonUtil.getCurrTimes());
        msg.setLiveStatus(liveStatus);
        client.sendMessage(msg);   
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getBusinessId() {
        return businessId;
    }

    public void setBusinessId(String businessId) {
        this.businessId = businessId;
    }

    public String getDeviceCode() {
        return deviceCode;
    }

    public void setDeviceCode(String deviceCode) {
        this.deviceCode = deviceCode;
    }

    public void setProcess(Process process) {
        this.process = process;
    }

    public Process getProcess() {
        return process;
    }

}
